﻿using Autodesk.AutoCAD.Runtime;
using System.Collections.Generic;
using Autodesk.AutoCAD.Geometry;
using Galaxy.AutoCAD.Geometrys;
using System;
using Galaxy.AutoCAD.Editors;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.GraphicsInterface;
using Galaxy.AutoCAD.Strings;
using Autodesk.AutoCAD.DatabaseServices;
using Galaxy.AutoCAD.Databases;

namespace Galaxy.AutoCAD.GraphicsInterface
{
    public class CloudLineRule : DrawableOverrule
    {
        #region 定义属性图层名，用来过滤需要重定义的多段线
        private string _layername = "Galaxy-云线";
        public string LayerName
        {
            get
            {
                return _layername;
            }
            set
            {
                _layername = value;
            }
        }
        #endregion
        #region 重载DrawableOverrule的WordDraw函数以把多段线重定义为云线
        public override bool WorldDraw(Drawable drawable, WorldDraw wd)
        {
            Autodesk.AutoCAD.DatabaseServices.Polyline pl = drawable as Autodesk.AutoCAD.DatabaseServices.Polyline;
            if (pl.NumberOfVertices == 4 && pl.Closed == true)
            {
                Point2dCollection pt2ds = new Point2dCollection();
                pt2ds.Add(pl.GetPoint2dAt(0));
                pt2ds.Add(pl.GetPoint2dAt(1));
                pt2ds.Add(pl.GetPoint2dAt(2));
                pt2ds.Add(pl.GetPoint2dAt(3));
                pt2ds.Add(pl.GetPoint2dAt(0));
                Vector2d vector2dOne = new Vector2d(pt2ds[1].X - pt2ds[0].X, pt2ds[1].Y - pt2ds[0].Y);
                Vector2d normalOne = vector2dOne.GetNormal();
                Vector2d vector2dTwo = new Vector2d(pt2ds[2].X - pt2ds[1].X, pt2ds[2].Y - pt2ds[1].Y);
                Vector2d normalTwo = vector2dTwo.GetNormal();
                Vector2d vector2dThree = new Vector2d(pt2ds[3].X - pt2ds[2].X, pt2ds[3].Y - pt2ds[2].Y);
                Vector2d normalThree = vector2dThree.GetNormal();
                Vector2d vector2Four = new Vector2d(pt2ds[4].X - pt2ds[3].X, pt2ds[4].Y - pt2ds[3].Y);
                Vector2d normalFour = vector2Four.GetNormal();
                if (pt2ds[0].GetDistanceTo(pt2ds[1]) <= 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[0]);
                    vertexPt2ds.Add(pt2ds[1]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[0].GetDistanceTo(pt2ds[1]) > 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[0]);
                    for (int i = 0; i < pt2ds[0].GetDistanceTo(pt2ds[1]) / 400 - 1; i++)
                    {
                        vertexPt2ds.Add(pt2ds[0] + 400 * normalOne * (i + 1));
                    }
                    vertexPt2ds.Add(pt2ds[1]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[1].GetDistanceTo(pt2ds[2]) <= 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[1]);
                    vertexPt2ds.Add(pt2ds[2]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[1].GetDistanceTo(pt2ds[2]) > 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[1]);
                    for (int i = 0; i < pt2ds[1].GetDistanceTo(pt2ds[2]) / 400 - 1; i++)
                    {
                        vertexPt2ds.Add(pt2ds[1] + 400 * normalTwo * (i + 1));
                    }
                    vertexPt2ds.Add(pt2ds[2]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[2].GetDistanceTo(pt2ds[3]) <= 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[2]);
                    vertexPt2ds.Add(pt2ds[3]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[2].GetDistanceTo(pt2ds[3]) > 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[2]);
                    for (int i = 0; i < pt2ds[2].GetDistanceTo(pt2ds[3]) / 400 - 1; i++)
                    {
                        vertexPt2ds.Add(pt2ds[2] + 400 * normalThree * (i + 1));
                    }
                    vertexPt2ds.Add(pt2ds[3]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[3].GetDistanceTo(pt2ds[4]) <= 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[3]);
                    vertexPt2ds.Add(pt2ds[4]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
                if (pt2ds[3].GetDistanceTo(pt2ds[4]) > 400)
                {
                    Point2dCollection vertexPt2ds = new Point2dCollection();
                    vertexPt2ds.Add(pt2ds[3]);
                    for (int i = 0; i < pt2ds[3].GetDistanceTo(pt2ds[4]) / 400 - 1; i++)
                    {
                        vertexPt2ds.Add(pt2ds[3] + 400 * normalFour * (i + 1));
                    }
                    vertexPt2ds.Add(pt2ds[4]);
                    Autodesk.AutoCAD.DatabaseServices.Polyline resultPl = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                    for (int i = 0; i < vertexPt2ds.Count; i++)
                    {
                        resultPl.AddVertexAt(i, vertexPt2ds[i], 1, 0, 50);
                    }
                    wd.Geometry.Polyline(resultPl, 0, 0);
                }
            }
            return true;
        }
        #endregion
        #region 重载DrawableOverrule的IsApplicable函数以过滤图层名为指定的图层名
        public override bool IsApplicable(RXObject overruledSubject)
        {
            Autodesk.AutoCAD.DatabaseServices.Polyline pl = overruledSubject as Autodesk.AutoCAD.DatabaseServices.Polyline;
            if (pl != null && LayerName != null)
            {
                string layerName = pl.Layer;
                if (layerName.Contains(LayerName))
                {
                    return true;
                }
            }
            return false;
        }
        #endregion
    }
}
